package com.xiaoye.qbdatahandle.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoye.qbdatahandle.config.XiaoYeConfig;
import com.xiaoye.qbdatahandle.domian.AjaxResult;
import com.xiaoye.qbdatahandle.domian.wiki.ContentInfo;
import com.xiaoye.qbdatahandle.domian.wiki.Wiki;
import com.xiaoye.qbdatahandle.entity.ImageEntity;
import com.xiaoye.qbdatahandle.service.FileDownloadService;
import com.xiaoye.qbdatahandle.util.MongoUtil;
import com.xiaoye.qbdatahandle.vo.ExportWikiVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@RestController
@RequestMapping("/wiki")
public class WikiController {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    FileDownloadService fileDownloadService;

    @GetMapping("/list")
    public AjaxResult list(@RequestParam int page, @RequestParam int size, Wiki wiki) {
        page = MongoUtil.getModalPn(page);
        Criteria criteria = new Criteria();
        // 标题模糊查询
        if (StringUtils.isNotBlank(wiki.getTitle())) {
            criteria.and("title").regex(wiki.getTitle());
        }
        // 关键词模糊查询
        if (StringUtils.isNotBlank(wiki.getKeywords())) {
            criteria.and("keywords").regex(wiki.getKeywords());
        }
        if (StringUtils.isNotBlank(wiki.getTid())) {
            criteria.and("_tid").is(new ObjectId(wiki.getTid()));
        }
        Query query = Query.query(criteria);
        // 创建分页参数
        Pageable pageable = PageRequest.of(page, size);
        long count = mongoTemplate.count(query, Wiki.class);
        query.with(Sort.by(Sort.Order.desc("publish_time"))).skip((long) page * size).limit(size);
        List<Wiki> list = mongoTemplate.find(query.with(pageable), Wiki.class);
        IPage<Wiki> pages = MongoUtil.getModalIPage(page, size, count, list);
        return AjaxResult.success(pages);
    }

    @PostMapping
    public AjaxResult add() {
        Wiki wiki = new Wiki();
        wiki.setImages(new ArrayList<>());
        wiki.setReferences(new ArrayList<>());
        wiki.setPublishTime(DateUtil.now());
        wiki.setTid("tid");
        wiki.setTitle("title");
        wiki.setKeywords("1,2,3");
        wiki.setLang("zh");
        wiki.setShortDesc("shortDesc");
        wiki.setDesc("desc");
        wiki.setSource("wikiSource");
        wiki.setThumbnailUrl("suoluetu");
        wiki.setType("type");
        wiki.setUrl("www.baidu.com");
        wiki.setAlbums(new ArrayList<>());
        wiki.setImages(new ArrayList<>());
        wiki.setQid("qid");
        wiki.setCanonicalLink("canonicalLink");
        wiki.setContentInfo(new ContentInfo());
        wiki.setIsAnalysis(false);
        wiki.setIsHandle(false);
        Wiki save = mongoTemplate.save(wiki);
        return AjaxResult.success();
    }

    @GetMapping("/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        Wiki wiki = mongoTemplate.findById(id, Wiki.class);
        if (wiki == null) {
            return AjaxResult.error("结果不存在");
        }
        return AjaxResult.success(wiki);
    }

    /**
     * @description: 导出文章数据
     * @author: ChenYao
     * @return: void
     * @ceateDate: 2025/2/27 上午3:27
     */
    @PostMapping("/export")
    public void export(@RequestBody ExportWikiVo wikiVo, HttpServletResponse response) {
        List<String> filePaths = new ArrayList<>();
        List<String> ids = wikiVo.getIds();
        String title = wikiVo.getTitle();
        // 根据标题模糊查询
        Criteria criteria = new Criteria();
        if (StringUtils.isNotBlank(title)) {
            criteria.and("title").regex(MongoUtil.getLike(title));
        }
        // 根据id查询
        if (ids != null && !ids.isEmpty()) {
            criteria.and("id").in(ids);
        }
        // 根据时间范围查询
        LocalDateTime startTime = wikiVo.getStartTime();
        LocalDateTime endTime = wikiVo.getEndTime();
        if (startTime != null && endTime != null) {
            criteria.and("publish_time").gte(MongoUtil.getModalTime(startTime)).lte(MongoUtil.getModalTime(endTime));
        }

        // 查询 所有文章数据
        List<Wiki> list = mongoTemplate.find(new Query(criteria), Wiki.class);
        if (list.isEmpty()) {
            log.info("查询文章数据为空");
            return;
        }
        list.forEach(wiki -> {

            // 导出文章图片
            List<ImageEntity> images = wiki.getImages();
            if (images == null || images.isEmpty()) {
                return;
            }
            StringBuffer contentImages = new StringBuffer();
            images.forEach(image -> {
                try {
                    String filename = image.getFilename();
                    if (StringUtils.isBlank(filename)) {
                        return;
                    }
                    //File file = new File(XiaoYeConfig.getProfile() + File.separator + filename);
                    File file = new File(filename);
                    log.info("下载路径:{}", file.getAbsolutePath());
                    fileDownloadService.downloadLargeFile(XiaoYeConfig.getImageWeb() + filename, file.getAbsolutePath());
                    contentImages.append(filename).append("\n");
                    // 图片路径
                    filePaths.add(file.getAbsolutePath());
                } catch (IOException e) {
                    log.error("导出文章图片失败", e);
                } catch (Exception e) {
                    log.error("导出文章图片不存在或其他异常", e);
                }
            });
            wiki.setContentImages(contentImages.toString());
        });


        // 数据导出成excel
        File excelFile = new File("wiki_" + UUID.fastUUID() + ".xlsx");
        log.info("wiki 数据准备写入excel,getAbsolutePath:{}", excelFile.getAbsolutePath());
        // 写入 Excel
        try {
            EasyExcel.write(excelFile, Wiki.class).sheet("wiki").doWrite(list);
            filePaths.add(excelFile.getAbsolutePath());
            downloadZip(filePaths, response);
            log.info("excel 生成完成");
        } catch (Exception e) {
            log.error("导出文章数据失败", e);

        }
    }

    public void downloadZip(List<String> imagePaths, HttpServletResponse response) throws IOException {
        // 图片路径列表

        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=wiki_" + UUID.fastUUID() + ".zip");

        // 将 ZIP 文件写入响应输出流
        try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
            for (String imagePath : imagePaths) {
                try (FileInputStream fis = new FileInputStream(imagePath)) {
                    log.info("ZIP写入文件:{}", imagePath);
                    ZipEntry zipEntry = new ZipEntry(getFileName(imagePath));
                    zipOut.putNextEntry(zipEntry);
                    byte[] bytes = new byte[1024];
                    int length;
                    while ((length = fis.read(bytes)) >= 0) {
                        zipOut.write(bytes, 0, length);
                    }
                }
            }
        }
    }

    public static String getFileName(String filePath) {
        File file = new File(filePath);
        return file.getName();
    }
}
